﻿using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System;
using SHomeWorkshop.LunarConcept.Controls;

namespace SHomeWorkshop.LunarConcept.Adorners
{
    /// <summary>
    /// 创建时间：2012年9月27日
    /// 创建者：  杨震宇
    /// 
    /// 主要用途：为ConetneWidget提供一个外框装饰器，用以拖出关系线和另一个节点。
    /// </summary>
    public class OuterBorderAdorner : Adorner
    {
        /// <summary>
        /// 用于内容部件的控制点。
        /// </summary>
        public OuterBorderAdorner(UIElement adornedElement, Widgets.ContentWidget masterWidget)
            : base(adornedElement)
        {
            this.masterWidget = masterWidget;

            //终于解决了选定装饰器中线条宽度为2而不是1像素的问题！！！
            this.SnapsToDevicePixels = false;
            this.SetValue(RenderOptions.EdgeModeProperty, EdgeMode.Unspecified);
            //this.Opacity = 0.75;
            //this.Cursor = System.Windows.Input.Cursors.SizeAll;

            this.MouseLeftButtonDown +=
                new System.Windows.Input.MouseButtonEventHandler(LineCtrlAdorner_MouseLeftButtonDown);
            //this.MouseEnter += new System.Windows.Input.MouseEventHandler(WidgetCenterAdorner_MouseEnter);
            //this.MouseLeave += new System.Windows.Input.MouseEventHandler(WidgetCenterAdorner_MouseLeave);
        }

        void WidgetCenterAdorner_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
        {
            this.InvalidateVisual();
        }

        void WidgetCenterAdorner_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
        {
            this.InvalidateVisual();
        }

        void LineCtrlAdorner_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (e.ClickCount == 2)
            {
                OnDoubleClicked(sender, e);
            }
        }

        public event EventHandler<System.Windows.Input.MouseButtonEventArgs> DoubleClicked;

        protected void OnDoubleClicked(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (DoubleClicked != null)
            {
                DoubleClicked(sender, e);
            }
        }

        private Widgets.ContentWidget masterWidget = null;

        protected override void OnRender(DrawingContext drawingContext)
        {
            if (masterWidget == null) return;
            if (LunarMind.Globals.MainWindow == null) return;

            double fontsize = LunarMind.Globals.MainWindow.DefaultFontSize;

            Rect rect = new Rect(AdornedElement.RenderSize);

            Point center = new Point(rect.Left + rect.Width / 2, rect.Top + rect.Height / 2);

            switch (masterWidget.OuterBorderType)
            {
                case Enums.OuterBorderType.Rect://默认矩形，由MainBorder来实现（这是最初的实现，不好改了）
                    {
                        break;//无须动作。
                    }
                case Enums.OuterBorderType.RoundRect://圆角矩形
                    {
                        drawingContext.DrawRoundedRectangle(null,
                            new Pen(this.masterWidget.WidgetLineColor, this.masterWidget.WidgetLineWidth),
                            new Rect(rect.Left - fontsize, rect.Top - fontsize, rect.Width + fontsize * 2, rect.Height + fontsize * 2),
                            fontsize, fontsize);
                        break;
                    }
                case Enums.OuterBorderType.Cross://缺角矩形
                    {
                        #region 缺角矩形

                        Rect realRect = new Rect(rect.Left - fontsize, rect.Top - fontsize, rect.Width + fontsize * 2, rect.Height + fontsize * 2);
                        PathGeometry pathGeometry = new PathGeometry();
                        PathFigure pathFighre = new PathFigure() { StartPoint = rect.TopLeft, IsClosed = true };
                        PolyLineSegment polyLineSegment = new PolyLineSegment();
                        polyLineSegment.Points = new PointCollection()
                        {
                            new Point(rect.Left,realRect.Top),
                            new Point(rect.Right,realRect.Top),
                            rect.TopRight,
                            new Point(realRect.Right,rect.Top),
                            new Point(realRect.Right,rect.Bottom),
                            rect.BottomRight,
                            new Point(rect.Right,realRect.Bottom),
                            new Point(rect.Left,realRect.Bottom),
                            rect.BottomLeft,
                            new Point(realRect.Left,rect.Bottom),
                            new Point(realRect.Left,rect.Top),
                            rect.TopLeft,
                        };

                        pathFighre.Segments.Add(polyLineSegment);
                        pathGeometry.Figures.Add(pathFighre);

                        drawingContext.DrawGeometry(null,
                            new Pen(this.masterWidget.WidgetLineColor, this.masterWidget.WidgetLineWidth),
                            pathGeometry);
                        #endregion
                        break;
                    }
                case Enums.OuterBorderType.Ellipse://椭圆形
                    {
                        #region 椭圆形
                        double r = Math.Sqrt(2);
                        double w = rect.Width * r;
                        double h = rect.Height * r;
                        Rect realRect = new Rect(rect.Left - (w - rect.Width) / 2,
                            rect.Top - (h - rect.Height) / 2, w, h);

                        drawingContext.DrawEllipse(null,
                            new Pen(this.masterWidget.WidgetLineColor, this.masterWidget.WidgetLineWidth),
                           center, w / 2, h / 2);
                        #endregion
                        break;
                    }
                case Enums.OuterBorderType.Rhomb://菱形
                    {
                        #region 菱形
                        double halfW = rect.Width / 2; double halfH = rect.Height / 2;

                        Rect realRect = new Rect(rect.Left - fontsize, rect.Top - fontsize, rect.Width + fontsize * 2, rect.Height + fontsize * 2);
                        PathGeometry pathGeometry = new PathGeometry();
                        PathFigure pathFighre = new PathFigure()
                        {
                            StartPoint = new Point(rect.Left - halfW, center.Y),
                            IsClosed = true
                        };


                        PolyLineSegment polyLineSegment = new PolyLineSegment();
                        polyLineSegment.Points = new PointCollection()
                        {
                            new Point(center.X,rect.Top-halfH),
                            new Point(rect.Right+halfW,center.Y),
                            new Point(center.X,rect.Bottom+halfH),
                        };

                        pathFighre.Segments.Add(polyLineSegment);
                        pathGeometry.Figures.Add(pathFighre);

                        drawingContext.DrawGeometry(null,
                            new Pen(this.masterWidget.WidgetLineColor, this.masterWidget.WidgetLineWidth),
                            pathGeometry);
                        #endregion
                        break;
                    }
                case Enums.OuterBorderType.LeftParallelogram://左平行四边形
                    {
                        #region 左平行四边形

                        double offcet = rect.Height / Math.Sqrt(3);

                        PathGeometry pathGeometry = new PathGeometry();
                        PathFigure pathFighre = new PathFigure()
                        {
                            StartPoint = new Point(rect.Left - offcet, rect.Bottom),
                            IsClosed = true
                        };


                        PolyLineSegment polyLineSegment = new PolyLineSegment();
                        polyLineSegment.Points = new PointCollection()
                        {
                            rect.TopLeft,
                            new Point(rect.Right+offcet,rect.Top),
                            rect.BottomRight,
                        };

                        pathFighre.Segments.Add(polyLineSegment);
                        pathGeometry.Figures.Add(pathFighre);

                        drawingContext.DrawGeometry(null,
                            new Pen(this.masterWidget.WidgetLineColor, this.masterWidget.WidgetLineWidth),
                            pathGeometry);

                        #endregion
                        break;
                    }
                case Enums.OuterBorderType.RightParallelogram://右平行四边形
                    {
                        #region 右平行四边形

                        double offcet = rect.Height / Math.Sqrt(3);

                        PathGeometry pathGeometry = new PathGeometry();
                        PathFigure pathFighre = new PathFigure()
                        {
                            StartPoint = new Point(rect.Left - offcet, rect.Top),
                            IsClosed = true
                        };


                        PolyLineSegment polyLineSegment = new PolyLineSegment();
                        polyLineSegment.Points = new PointCollection()
                        {
                            rect.TopRight,
                            new Point(rect.Right+offcet,rect.Bottom),
                            rect.BottomLeft,
                        };

                        pathFighre.Segments.Add(polyLineSegment);
                        pathGeometry.Figures.Add(pathFighre);

                        drawingContext.DrawGeometry(null,
                            new Pen(this.masterWidget.WidgetLineColor, this.masterWidget.WidgetLineWidth),
                            pathGeometry);

                        #endregion
                        break;
                    }
                case Enums.OuterBorderType.SixSideShape://六边形
                    {
                        #region 六边形

                        double offcet = rect.Height / 2 / Math.Sqrt(3);

                        PathGeometry pathGeometry = new PathGeometry();
                        PathFigure pathFighre = new PathFigure()
                        {
                            StartPoint = new Point(rect.Left - offcet, center.Y),
                            IsClosed = true
                        };


                        PolyLineSegment polyLineSegment = new PolyLineSegment();
                        polyLineSegment.Points = new PointCollection()
                        {
                            rect.TopLeft,rect.TopRight,
                            new Point(rect.Right+offcet,center.Y),
                            rect.BottomRight,rect.BottomLeft,
                        };

                        pathFighre.Segments.Add(polyLineSegment);
                        pathGeometry.Figures.Add(pathFighre);

                        drawingContext.DrawGeometry(null,
                            new Pen(this.masterWidget.WidgetLineColor, this.masterWidget.WidgetLineWidth),
                            pathGeometry);

                        #endregion
                        break;
                    }
                case Enums.OuterBorderType.EightSidedShape://八边形
                    {
                        #region 八边形

                        Rect realRect = new Rect(rect.Left - fontsize, rect.Top - fontsize, rect.Width + fontsize * 2, rect.Height + fontsize * 2);
                        PathGeometry pathGeometry = new PathGeometry();
                        PathFigure pathFighre = new PathFigure()
                        {
                            StartPoint = new Point(rect.Left, realRect.Top),
                            IsClosed = true
                        };
                        PolyLineSegment polyLineSegment = new PolyLineSegment();
                        polyLineSegment.Points = new PointCollection()
                        {
                            new Point(rect.Right,realRect.Top),
                            new Point(realRect.Right,rect.Top),
                            new Point(realRect.Right,rect.Bottom),
                            new Point(rect.Right,realRect.Bottom),
                            new Point(rect.Left,realRect.Bottom),
                            new Point(realRect.Left,rect.Bottom),
                            new Point(realRect.Left,rect.Top),
                        };

                        pathFighre.Segments.Add(polyLineSegment);
                        pathGeometry.Figures.Add(pathFighre);

                        drawingContext.DrawGeometry(null,
                            new Pen(this.masterWidget.WidgetLineColor, this.masterWidget.WidgetLineWidth),
                            pathGeometry);
                        #endregion
                        break;
                    }
                case Enums.OuterBorderType.FillArrowLeft://左平底箭头
                    {
                        #region 左平底箭头

                        double offcet = rect.Height / 2 / Math.Sqrt(3);

                        PathGeometry pathGeometry = new PathGeometry();
                        PathFigure pathFighre = new PathFigure()
                        {
                            StartPoint = new Point(rect.Left - offcet, center.Y),
                            IsClosed = true
                        };


                        PolyLineSegment polyLineSegment = new PolyLineSegment();
                        polyLineSegment.Points = new PointCollection()
                        {
                            rect.TopLeft,rect.TopRight,
                            rect.BottomRight,rect.BottomLeft,
                        };

                        pathFighre.Segments.Add(polyLineSegment);
                        pathGeometry.Figures.Add(pathFighre);

                        drawingContext.DrawGeometry(null,
                            new Pen(this.masterWidget.WidgetLineColor, this.masterWidget.WidgetLineWidth),
                            pathGeometry);

                        #endregion
                        break;
                    }
                case Enums.OuterBorderType.FillArrowRight://右平底箭头
                    {
                        #region 右平底箭头

                        double offcet = rect.Height / 2 / Math.Sqrt(3);

                        PathGeometry pathGeometry = new PathGeometry();
                        PathFigure pathFighre = new PathFigure()
                        {
                            StartPoint = rect.TopLeft,
                            IsClosed = true
                        };


                        PolyLineSegment polyLineSegment = new PolyLineSegment();
                        polyLineSegment.Points = new PointCollection()
                        {
                            rect.TopRight,
                            new Point(rect.Right+offcet,center.Y),
                            rect.BottomRight,rect.BottomLeft,
                        };

                        pathFighre.Segments.Add(polyLineSegment);
                        pathGeometry.Figures.Add(pathFighre);

                        drawingContext.DrawGeometry(null,
                            new Pen(this.masterWidget.WidgetLineColor, this.masterWidget.WidgetLineWidth),
                            pathGeometry);

                        #endregion
                        break;
                    }
                case Enums.OuterBorderType.FillArrowTop://上平底箭头
                    {
                        #region 上平底箭头

                        double offcet = rect.Width / 2 / Math.Sqrt(3);

                        PathGeometry pathGeometry = new PathGeometry();
                        PathFigure pathFighre = new PathFigure()
                        {
                            StartPoint = rect.TopLeft,
                            IsClosed = true
                        };


                        PolyLineSegment polyLineSegment = new PolyLineSegment();
                        polyLineSegment.Points = new PointCollection()
                        {
                            new Point(center.X,rect.Top-offcet),
                            rect.TopRight,rect.BottomRight,rect.BottomLeft,
                        };

                        pathFighre.Segments.Add(polyLineSegment);
                        pathGeometry.Figures.Add(pathFighre);

                        drawingContext.DrawGeometry(null,
                            new Pen(this.masterWidget.WidgetLineColor, this.masterWidget.WidgetLineWidth),
                            pathGeometry);

                        #endregion
                        break;
                    }
                case Enums.OuterBorderType.FillArrowBottom://下平底箭头
                    {
                        #region 下平底箭头

                        double offcet = rect.Width / 2 / Math.Sqrt(3);

                        PathGeometry pathGeometry = new PathGeometry();
                        PathFigure pathFighre = new PathFigure()
                        {
                            StartPoint = rect.TopLeft,
                            IsClosed = true
                        };


                        PolyLineSegment polyLineSegment = new PolyLineSegment();
                        polyLineSegment.Points = new PointCollection()
                        {                            
                            rect.TopRight,rect.BottomRight,
                            new Point(center.X,rect.Bottom+offcet),
                            rect.BottomLeft,
                        };

                        pathFighre.Segments.Add(polyLineSegment);
                        pathGeometry.Figures.Add(pathFighre);

                        drawingContext.DrawGeometry(null,
                            new Pen(this.masterWidget.WidgetLineColor, this.masterWidget.WidgetLineWidth),
                            pathGeometry);

                        #endregion
                        break;
                    }
                case Enums.OuterBorderType.ArrowLeft://左燕尾箭头
                    {
                        #region 左燕尾箭头

                        double offcet = rect.Height / 2 / Math.Sqrt(3);

                        PathGeometry pathGeometry = new PathGeometry();
                        PathFigure pathFighre = new PathFigure()
                        {
                            StartPoint = new Point(rect.Left - offcet, center.Y),
                            IsClosed = true
                        };


                        PolyLineSegment polyLineSegment = new PolyLineSegment();
                        polyLineSegment.Points = new PointCollection()
                        {
                            rect.TopLeft,
                            new Point(rect.Right+offcet,rect.Top),
                            new Point(rect.Right,center.Y),
                            new Point(rect.Right+offcet,rect.Bottom),
                            rect.BottomLeft,
                        };

                        pathFighre.Segments.Add(polyLineSegment);
                        pathGeometry.Figures.Add(pathFighre);

                        drawingContext.DrawGeometry(null,
                            new Pen(this.masterWidget.WidgetLineColor, this.masterWidget.WidgetLineWidth),
                            pathGeometry);

                        #endregion
                        break;
                    }
                case Enums.OuterBorderType.ArrowRight://右燕尾箭头
                    {
                        #region 右燕尾箭头

                        double offcet = rect.Height / 2 / Math.Sqrt(3);

                        PathGeometry pathGeometry = new PathGeometry();
                        PathFigure pathFighre = new PathFigure()
                        {
                            StartPoint = new Point(rect.Left - offcet, rect.Top),
                            IsClosed = true
                        };


                        PolyLineSegment polyLineSegment = new PolyLineSegment();
                        polyLineSegment.Points = new PointCollection()
                        {
                            rect.TopRight,
                            new Point(rect.Right+offcet,center.Y),
                            rect.BottomRight,
                            new Point(rect.Left-offcet,rect.Bottom),
                            new Point(rect.Left,center.Y),
                        };

                        pathFighre.Segments.Add(polyLineSegment);
                        pathGeometry.Figures.Add(pathFighre);

                        drawingContext.DrawGeometry(null,
                            new Pen(this.masterWidget.WidgetLineColor, this.masterWidget.WidgetLineWidth),
                            pathGeometry);

                        #endregion
                        break;
                    }
                case Enums.OuterBorderType.ArrowTop://上燕尾箭头
                    {
                        #region 上燕尾箭头

                        double offcet = rect.Width / 2 / Math.Sqrt(3);

                        PathGeometry pathGeometry = new PathGeometry();
                        PathFigure pathFighre = new PathFigure()
                        {
                            StartPoint = rect.TopLeft,
                            IsClosed = true
                        };

                        PolyLineSegment polyLineSegment = new PolyLineSegment();
                        polyLineSegment.Points = new PointCollection()
                        {
                            new Point(center.X,rect.Top-offcet),
                            rect.TopRight,
                            new Point(rect.Right,rect.Bottom+offcet),
                            new Point(center.X,rect.Bottom),
                            new Point(rect.Left,rect.Bottom+offcet),
                        };

                        pathFighre.Segments.Add(polyLineSegment);
                        pathGeometry.Figures.Add(pathFighre);

                        drawingContext.DrawGeometry(null,
                            new Pen(this.masterWidget.WidgetLineColor, this.masterWidget.WidgetLineWidth),
                            pathGeometry);

                        #endregion
                        break;
                    }
                case Enums.OuterBorderType.ArrowBottom://下燕尾箭头
                    {
                        #region 下燕尾箭头

                        double offcet = rect.Width / 2 / Math.Sqrt(3);

                        PathGeometry pathGeometry = new PathGeometry();
                        PathFigure pathFighre = new PathFigure()
                        {
                            StartPoint = new Point(rect.Left, rect.Top - offcet),
                            IsClosed = true
                        };


                        PolyLineSegment polyLineSegment = new PolyLineSegment();
                        polyLineSegment.Points = new PointCollection()
                        {                   
                            new Point(center.X,rect.Top),
                            new Point(rect.Right,rect.Top-offcet),
                            rect.BottomRight,
                            new Point(center.X,rect.Bottom+offcet),
                            rect.BottomLeft,
                        };

                        pathFighre.Segments.Add(polyLineSegment);
                        pathGeometry.Figures.Add(pathFighre);

                        drawingContext.DrawGeometry(null,
                            new Pen(this.masterWidget.WidgetLineColor, this.masterWidget.WidgetLineWidth),
                            pathGeometry);

                        #endregion
                        break;
                    }
            }
        }
    }
}